package cn.stylefeng.guns.modular.robot.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.guns.core.common.exception.BizExceptionEnum;
import cn.stylefeng.guns.core.common.page.LayuiPageFactory;
import cn.stylefeng.guns.core.common.page.LayuiPageInfo;
import cn.stylefeng.guns.core.shiro.ShiroKit;
import cn.stylefeng.guns.core.shiro.ShiroUser;
import cn.stylefeng.guns.modular.robot.entity.Group;
import cn.stylefeng.guns.modular.robot.entity.GroupRelationship;
import cn.stylefeng.guns.modular.robot.entity.Order;
import cn.stylefeng.guns.modular.robot.entity.enums.GroupMode;
import cn.stylefeng.guns.modular.robot.entity.enums.GroupType;
import cn.stylefeng.guns.modular.robot.entity.vo.req.GroupListReq;
import cn.stylefeng.guns.modular.robot.entity.vo.resp.GroupListResp;
import cn.stylefeng.guns.modular.robot.mapper.GroupMapper;
import cn.stylefeng.guns.modular.robot.service.GroupRelationshipService;
import cn.stylefeng.guns.modular.robot.service.GroupService;
import cn.stylefeng.guns.modular.robot.service.OrderService;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements GroupService {

    @Resource
    private GroupRelationshipService groupRelationshipService;
    @Resource
    private OrderService orderService;

    @Override
    public Group getGroupByTgGroupId(Long groupId) {
        List<Group> groups = lambdaQuery()
                .eq(Group::getTgGroupId, groupId)
                .list();
        if (CollectionUtil.isEmpty(groups)) {
            return null;
        }
        return groups.get(0);
    }

    @Override
    public void addGroup(GroupListReq groupListReq) {
        ShiroUser shiroUser = ShiroKit.getUserNotNull();
        GroupType type = groupListReq.getType();
        if(GroupType.DF.equals(type)){
            List<Group> list = lambdaQuery()
                    .eq(Group::getCreateBy, shiroUser.getAccount())
                    .eq(Group::getType, type)
                    .list();
            if(!CollectionUtils.isEmpty(list)){
                throw new ServiceException(BizExceptionEnum.DF_GROUP_EXISTS);
            }
        }
        if (StringUtils.isBlank(groupListReq.getName())) {
            throw new ServiceException(BizExceptionEnum.USER_NAME_EMPTY);
        }
        List<Group> list = lambdaQuery()
                .eq(Group::getTgGroupId, groupListReq.getTgGroupId())
                .list();
        if (!CollectionUtil.isEmpty(list)) {
            throw new ServiceException(BizExceptionEnum.GROUP_ID_EXISTS);
        }
        Group group = new Group();
        group.setRate(groupListReq.getRate().divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP));
        group.setExchangeRate(groupListReq.getExchangeRate());
        group.setExtract(groupListReq.getExtract());
        if (group.getExchangeRate().compareTo(BigDecimal.valueOf(0)) == 0) {
            group.setGroupMode(GroupMode.币);
        } else {
            group.setGroupMode(GroupMode.USDT);
        }
        group.setType(groupListReq.getType());
        group.setUnit(groupListReq.getUnit());
        group.setTgGroupId(groupListReq.getTgGroupId());
        group.setMemo(groupListReq.getMemo());
        group.setName(groupListReq.getName());
        group.setUserName(groupListReq.getUserName());
        group.setCreateTime(new Date());
        group.setCreateBy(shiroUser.getAccount());
        save(group);
    }

    @Override
    public void edit(GroupListReq groupListReq) {
        if (groupListReq.getId() == null) {
            throw new ServiceException(BizExceptionEnum.ID_EMPTY);
        }
        ShiroUser shiroUser = ShiroKit.getUserNotNull();
        Group group = getById(groupListReq.getId());
        group.setRate(groupListReq.getRate().divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP));
        group.setExchangeRate(groupListReq.getExchangeRate());
        group.setExtract(groupListReq.getExtract());
        if (group.getExchangeRate().compareTo(BigDecimal.valueOf(0)) == 0) {
            group.setGroupMode(GroupMode.币);
        } else {
            group.setGroupMode(GroupMode.USDT);
        }
        group.setUnit(groupListReq.getUnit());
        group.setTgGroupId(groupListReq.getTgGroupId());
        group.setMemo(groupListReq.getMemo());
        group.setName(groupListReq.getName());
        group.setUserName(groupListReq.getUserName());
        group.setUpdateBy(shiroUser.getAccount());
        group.setUpdateTime(new Date());
        updateById(group);
    }

    @Override
    public LayuiPageInfo list(Long tgGroupId, String name, String userName, Long pageSize, Long pageNum) {
        String account = ShiroKit.getUser().getAccount();
        IPage<GroupListResp> groupListVOIPage = new Page<>();
        IPage<Group> groupIPage = lambdaQuery()
                .eq(!"admin".equals(account), Group::getCreateBy, account)
                .eq(tgGroupId != null, Group::getTgGroupId, tgGroupId)
                .like(StringUtils.isNotBlank(name), Group::getName, name)
                .like(StringUtils.isNotBlank(userName), Group::getUserName, userName)
                .orderByDesc(Group::getCreateTime)
                .page(new Page<>(pageNum, pageSize));
        List<Group> groups = groupIPage.getRecords();
        if (CollectionUtil.isEmpty(groups)) {
            return LayuiPageFactory.createPageInfo(groupListVOIPage);
        }
        groupListVOIPage.setPages(groupIPage.getPages());
        groupListVOIPage.setCurrent(groupIPage.getCurrent());
        groupListVOIPage.setSize(groupIPage.getSize());
        groupListVOIPage.setTotal(groupIPage.getTotal());
        //下游群id
        Set<Long> groupIds = groups.stream().filter(group -> group.getUpGroup() != null && !group.getUpGroup()).map(Group::getTgGroupId).collect(Collectors.toSet());
        if (CollectionUtil.isEmpty(groupIds)) {
            List<GroupListResp> groupListResps = new ArrayList<>();
            for (Group group : groups) {
                GroupListResp groupListResp = new GroupListResp();
                BeanUtils.copyProperties(group, groupListResp);
                groupListResps.add(groupListResp);
            }
            groupListVOIPage.setRecords(groupListResps);
            return LayuiPageFactory.createPageInfo(groupListVOIPage);
        }
        List<GroupRelationship> groupRelationships = groupRelationshipService.lambdaQuery()
                .in(GroupRelationship::getSendGroupId, groupIds)
                .list();
        if (CollectionUtil.isEmpty(groupRelationships)) {
            List<GroupListResp> groupListResps = new ArrayList<>();
            for (Group group : groups) {
                GroupListResp groupListResp = new GroupListResp();
                BeanUtils.copyProperties(group, groupListResp);
                groupListResps.add(groupListResp);
            }
            groupListVOIPage.setRecords(groupListResps);
            return LayuiPageFactory.createPageInfo(groupListVOIPage);
        }
        //群关系信息
        Map<Long, Long> map = new HashMap<>();
        for (GroupRelationship groupRelationship : groupRelationships) {
            map.put(groupRelationship.getSendGroupId(), groupRelationship.getReceiveGroupId());
        }
        List<GroupListResp> groupListVOS = new ArrayList<>();
        for (Group group : groups) {
            GroupListResp groupListVO = new GroupListResp();
            BeanUtils.copyProperties(group, groupListVO);
            if (group.getUpGroup() != null && !group.getUpGroup()) {
                Long upGroupId = map.get(group.getTgGroupId());
                groupListVO.setReceiveGroupId(upGroupId);
            }
            groupListVO.setRate(group.getRate() == null ? BigDecimal.valueOf(0) : group.getRate().multiply(BigDecimal.valueOf(100)));
            groupListVOS.add(groupListVO);
        }
        groupListVOIPage.setRecords(groupListVOS);
        return LayuiPageFactory.createPageInfo(groupListVOIPage);
    }

    @Override
    public ResponseData detail(Long id) {
        Group group = getById(id);
        GroupListResp groupListResp = new GroupListResp();
        BeanUtils.copyProperties(group, groupListResp);
        if (!Boolean.TRUE.equals(groupListResp.getUpGroup())) {
            List<GroupRelationship> groupRelationships = groupRelationshipService.lambdaQuery()
                    .eq(GroupRelationship::getSendGroupId, group.getTgGroupId())
                    .list();
            if (!CollectionUtil.isEmpty(groupRelationships)) {
                GroupRelationship groupRelationship = groupRelationships.get(0);
                groupListResp.setReceiveGroupId(groupRelationship.getReceiveGroupId());
                groupListResp.setRate(groupListResp.getRate() == null ? BigDecimal.valueOf(0) : groupListResp.getRate().multiply(BigDecimal.valueOf(100)));
            }
        }
        return ResponseData.success(groupListResp);
    }

    @Override
    public void delete(Long id) {
        Group group = getById(id);
        //删除群
        removeById(id);
        //删除群订单
        List<Order> orders = orderService.lambdaQuery()
                .eq(Order::getGroupId, group.getTgGroupId())
                .list();
        if (!CollectionUtils.isEmpty(orders)) {
            orderService.removeByIds(orders.stream().map(Order::getId).collect(Collectors.toList()));
        }
        //解除群关系
        List<GroupRelationship> groupRelationships = groupRelationshipService.lambdaQuery()
                .eq(GroupRelationship::getSendGroupId, group.getTgGroupId())
                .or()
                .eq(GroupRelationship::getReceiveGroupId, group.getTgGroupId())
                .list();
        if (CollectionUtils.isEmpty(groupRelationships)) {
            return;
        }
        groupRelationshipService.removeByIds(groupRelationships.stream().map(GroupRelationship::getId).collect(Collectors.toList()));
        //清除group up_group标记
        List<Long> groupIds = groupRelationships.stream().map(e -> group.getTgGroupId().equals(e.getSendGroupId()) ? e.getReceiveGroupId() : e.getSendGroupId()).collect(Collectors.toList());
        if (!Boolean.TRUE.equals(group.getUpGroup())) {
            //如果是下游群,查询上游群
            List<Group> groups = lambdaQuery()
                    .in(Group::getTgGroupId, groupIds)
                    .list();
            //一个下游群只有一个上游群
            Group grp = groups.get(0);
            List<GroupRelationship> groupRelationshipList = groupRelationshipService.lambdaQuery()
                    .eq(GroupRelationship::getReceiveGroupId, grp.getTgGroupId())
                    .list();
            //如果这个上游群还有下游群那上游群不需要更新
            if (!CollectionUtils.isEmpty(groupRelationshipList)) {
                return;
            }
        }
        UpdateWrapper<Group> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("tg_group_id", groupIds);
        updateWrapper.set("up_group", null);
        update(updateWrapper);
    }
}
